package io.kimmking.dubbo.common.dubboLB;

import java.util.concurrent.atomic.LongAdder;

public class myStatItem {
    private String name;
    private long lastResetTime;
    private long interval;
    //LongAdder使用了分段锁，所以并发性能上优于AutoInteger
    private LongAdder token;
    private int rate;

    myStatItem(String name, int rate, long interval) {
        this.name = name;
        this.rate = rate;
        this.interval = interval;
        this.lastResetTime = System.currentTimeMillis();
        this.token = this.buildLongAdder(rate);
    }

    public boolean isAllowable() {
        long now = System.currentTimeMillis();
        //如果距离上次被调用时间大于interval的时长，则Tps恢复至初始值
        if (now > this.lastResetTime + this.interval) {
            this.token = this.buildLongAdder(this.rate);
            this.lastResetTime = now;
        }

        //如果当前的吞吐量超过Tps，则限制当前调用
        if (this.token.sum() < 0L) {
            return false;
        } else {
            //每调用一次，可用的调用次数在原来的基础上减一
            this.token.decrement();
            return true;
        }
    }

    public long getInterval() {
        return this.interval;
    }

    public int getRate() {
        return this.rate;
    }

    long getLastResetTime() {
        return this.lastResetTime;
    }

    long getToken() {
        return this.token.sum();
    }

    public String toString() {
        return (new StringBuilder(32)).append("StatItem ").append("[name=").append(this.name).append(", ").append("rate = ").append(this.rate).append(", ").append("interval = ").append(this.interval).append("]").toString();
    }

    private LongAdder buildLongAdder(int rate) {
        LongAdder adder = new LongAdder();
        adder.add((long)rate);
        return adder;
    }
}
